package com.banmao.youZone.util;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.banmao.youZone.entity.Holiday;
import com.banmao.youZone.mapper.HolidayMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Component
public class CacheUtil {

    private static HolidayMapper holidayMapper;

    @Resource
    public void setHolidayMapper(HolidayMapper holidayMapper) {
        CacheUtil.holidayMapper = holidayMapper;
    }

    private static final Cache<String, Map<String, Holiday>> MAP_CACHE = CacheBuilder.newBuilder()
            .expireAfterAccess(1, TimeUnit.DAYS)
            .maximumSize(2)
            .build();

    private static final Cache<String, List<Holiday>> LIST_CACHE = CacheBuilder.newBuilder()
            .expireAfterAccess(5, TimeUnit.DAYS)
            .maximumSize(1)
            .build();

    public static Map<String, Holiday> getHolidayMap() {
        Map<String, Holiday> map = MAP_CACHE.getIfPresent("HOLIDAY_MAP");
        if (map != null) {
            return map;
        }

        List<Holiday> holidays = CacheUtil.getHolidaysAndWorkdays();

        Map<String, Holiday> allHolidayMap = holidays.stream()
                .filter(h -> h.getHoliday())
                .collect(Collectors.toMap(h -> DateUtil.format(h.getDate(), DatePattern.NORM_DATE_FORMAT),
                        h -> h, (oldV, newV) -> oldV));

        MAP_CACHE.put("HOLIDAY_MAP", allHolidayMap);

        return allHolidayMap;
    }

    public static Map<String, Holiday> getWorkdayMap() {
        Map<String, Holiday> map = MAP_CACHE.getIfPresent("WORKDAY_MAP");
        if (map != null) {
            return map;
        }

        List<Holiday> holidays = CacheUtil.getHolidaysAndWorkdays();

        Map<String, Holiday> allWorkdayMap = holidays.stream()
                .filter(h -> !h.getHoliday())
                .collect(Collectors.toMap(h -> DateUtil.format(h.getDate(), DatePattern.NORM_DATE_FORMAT),
                        h -> h, (oldV, newV) -> oldV));

        MAP_CACHE.put("WORKDAY_MAP", allWorkdayMap);

        return allWorkdayMap;
    }

    public static synchronized List<Holiday> getHolidaysAndWorkdays() {

        List<Holiday> list = LIST_CACHE.getIfPresent("ALL_HOLIDAYSANDWORKDAYS");
        if (list != null) {
            return list;
        }

        DateTime currentDateTime = DateUtil.date();
        List<Holiday> holidays = holidayMapper.selectList(Wrappers.<Holiday>lambdaQuery()
                .eq(Holiday::getYear, currentDateTime.year())
                .orderByAsc(Holiday::getDate));
        if (currentDateTime.isAfter(new DateTime(currentDateTime.year() + "-12-25",
                DatePattern.NORM_DATE_FORMAT))) {
            List<Holiday> nextYearHolidayList = holidayMapper.selectList(Wrappers.<Holiday>lambdaQuery()
                    .eq(Holiday::getYear, currentDateTime.year() + 1)
                    .ltSql(Holiday::getDate, "'" + (currentDateTime.year() + 1) + "-06-01'")
                    .orderByAsc(Holiday::getDate));
            if (nextYearHolidayList == null) {
                throw new RuntimeException("需要获取明年的节假日了");
            }
            holidays.addAll(nextYearHolidayList);
        }
        LIST_CACHE.put("ALL_HOLIDAYSANDWORKDAYS", holidays);

        return holidays;
    }


}
